﻿package net.pezzato.genetree.graphics{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.geom.Point;
	import net.pezzato.graphics.Widget;
	import net.pezzato.genetree.info.GeneNode;
	import net.pezzato.genetree.graphics.NodeWidget;
	import net.pezzato.genetree.graphics.Link;
	import net.pezzato.genetree.graphics.Container;
	public class Sky extends Widget {
		private var scrollIncrement_:Number;
		private var container_:Container;
		private var movement_:Number;
		private var targetPosX_:Number;
		private var targetPosY_:Number;
		private var targetZoom_:Number;
		private var defaultPosX_:Number;
		private var defaultPosY_:Number;
		private var startNode_:GeneNode;
		private var startNodeWidget_:FullNodeWidget;
		private var lens_:Lens;
		private static const DEFAULT_SCALE_FACTOR:Number = 1.1;
		public function Sky(wp:Widget) {
			super(wp);
			drawBg();
			lens_ = new Lens(this);
			container_ = new Container(lens_);
			targetZoom_ = 1;
			defaultPosX_ = width/2;
			defaultPosY_ = height/2;
			lens_.x = defaultPosX_;
			lens_.y = defaultPosY_;
			scrollIncrement_ = height / 2;
			movement_ = 0;
			startNode_ = null;
			doubleClickEnabled = true;
			addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);
			addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			addEventListener(Event.ENTER_FRAME, moveToTarget);
		}
		public function startTreeFrom(node:GeneNode):NodeWidget {
			startNode_ = node;
			startNodeWidget_ = new FullNodeWidget(container_, node);
			startNodeWidget_.depth = 0;
			startNodeWidget_.addParents();
			return startNodeWidget_;
		}
		public function addNode(node:GeneNode, onw:NodeWidget = null):NodeWidget {
				return container_.addNode(node, onw);
		}
		public function centerStartNode():void {
			movement_ = 12;
			targetZoom_ = 1;
			targetPosX_ = -NodeWidget.EXPA_RECT.width / 2;
			targetPosY_ = -NodeWidget.EXPA_RECT.height / 2;
			startNodeWidget_.expand();
		}
		private function onMouseWheel(event:MouseEvent):void {
				if (event.delta > 0) {
					zoomIn();
				}
				if (event.delta < 0) {
					zoomOut();
				}
		}
		private function onDoubleClick(event:MouseEvent):void {
				if (event.target is NodeWidget) {
					var nw:NodeWidget = (event.target as NodeWidget);
					if (event.target.isExpanded) {
						targetZoom_ = Math.pow(2, nw.depth);
						targetPosX_ = - nw.x - NodeWidget.EXPA_RECT.width / targetZoom_ / 2;
						targetPosY_ = - nw.y  - NodeWidget.EXPA_RECT.height / targetZoom_ / 2;
						movement_ = 12;
					}
				}
		}
		private function onMouseDown(event:MouseEvent):void {
			container_.startDrag();
		}
		private function calculateZoom(tx:Number):Number {
			return (3 * NodeWidget.COMP_RECT.width + 4 * NodeWidget.X_MARGIN) / (2 * tx + 4 * NodeWidget.COMP_RECT.width + 4 * NodeWidget.X_MARGIN)
		}
		private function onMouseUp(event:MouseEvent):void {
			var changeZoom:Boolean = container_.dragged;
			container_.stopDrag();
			if (changeZoom) {
				movement_ = 12;
				targetPosX_ = container_.x;
				targetPosY_ = container_.y;
				targetZoom_ = calculateZoom(container_.x);
				trace(container_.x , targetZoom_);
			}
		}
		private function drawBg():void {
			graphics.beginFill(0x000000, 0);
			graphics.drawRect(0,0,parent.width,parent.height);
		}
		private function zoomIn():void {
			movement_ = 12;
			targetPosX_ = container_.x;
			targetPosY_ = container_.y;
			targetZoom_ = lens_.zoom * 2;
		}
		private function zoomOut():void {
			movement_ = 12;
			targetPosX_ = container_.x;
			targetPosY_ = container_.y;
			targetZoom_ = lens_.zoom / 2;
		}
		private function scrollLeft():void {
			movement_ = 12;
			targetPosX_ = container_.x + scrollIncrement_;
			targetPosY_ = container_.y;
			targetZoom_ = lens_.zoom;
		}
		private function scrollRight():void {
			movement_ = 12;
			targetPosX_ = container_.x - scrollIncrement_;
			targetPosY_ = container_.y;
			targetZoom_ = lens_.zoom;
		}
		private function moveToTarget(event:Event):void {
			if (movement_ > 0) {
				container_.x = (targetPosX_ + container_.x) / 2;
				container_.y = (targetPosY_ + container_.y) / 2;
				lens_.zoom = (DEFAULT_SCALE_FACTOR * targetZoom_ + lens_.zoom) /2;
				--movement_;
			}
		}
	}
}